﻿// <copyright file="HttpHandler.cs" company="DotNetLib">
//
// .netlib: http://www.codeplex.com/DotNetLib
//
// This code is released under the New BSD License.
// A copy of this license is available at:
// http://www.codeplex.com/DotNetLib/license
//
// </copyright>

namespace DotNetLib.Web
{
  using System;
  using System.Net;
  using System.Web;

  /// <summary>
  /// Base class for custom <see cref="IHttpHandler"/> implementations.
  /// </summary>
  public abstract class HttpHandler : IHttpHandler
  {
    /// <summary>
    /// Initializes a new instance of the <see cref="HttpHandler"/> class.
    /// </summary>
    protected HttpHandler()
    {
    }

    /// <summary>
    /// Gets a value indicating whether this instance can be reused between successive requests.
    /// </summary>
    public virtual bool IsReusable
    {
      get
      {
        return true;
      }
    }

    /// <summary>
    /// Gets the MIME type of the response for this request.
    /// </summary>
    protected virtual string ContentMimeType
    {
      get
      {
        return "text/html";
      }
    }

    /// <summary>
    /// Gets a value indicating whether this handler requires authentication.
    /// </summary>
    protected virtual bool RequiresAuthentication
    {
      get
      {
        return false;
      }
    }

    /// <summary>
    /// Processes the incoming HTTP request.
    /// </summary>
    /// <param name="context">The <see cref="HttpContext"/> for the request.</param>
    public abstract void ProcessRequestCore(HttpContext context);

    /// <summary>
    /// Process the incoming HTTP request.
    /// </summary>
    /// <param name="context">The <see cref="HttpContext"/> for the request.</param>
    public void ProcessRequest(HttpContext context)
    {
      this.SetResponseCachePolicy(context.Response.Cache);

      if (!this.ValidateParameters(context))
      {
        context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
        context.Response.End();
        return;
      }

      if (this.RequiresAuthentication && !context.Request.IsAuthenticated)
      {
        context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
        context.Response.End();
        return;
      }

      context.Response.ContentType = this.ContentMimeType;

      this.ProcessRequestCore(context);
    }

    /// <summary>
    /// Validates the incoming parameters.  Defaults to <b>true</b>.
    /// </summary>
    /// <param name="context">The <see cref="HttpContext"/> for the request.</param>
    /// <returns><b>True</b> if not implemented.</returns>
    protected virtual bool ValidateParameters(HttpContext context)
    {
      return true;
    }

    /// <summary>
    /// Sets the cacheability of the response.  Deafults to none.
    /// </summary>
    /// <param name="cache">The policy object.</param>
    protected virtual void SetResponseCachePolicy(HttpCachePolicy cache)
    {
      cache.SetCacheability(HttpCacheability.NoCache);
      cache.SetNoStore();
      cache.SetExpires(DateTime.MinValue);
    }
  }
}
